﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Forms.Integration;
using System.IO;
using System.Windows.Interop;
using VideoClipNameHelper;

namespace ClipPlayer
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, IDisposable
    {
        //
        VideoClipNameHelper.ConfigPaths cp = new VideoClipNameHelper.ConfigPaths();
        //
        AxAXVLC.AxVLCPlugin2 vlc = new AxAXVLC.AxVLCPlugin2();
        //
        private VideoClipNameHelper.MediaDirectory md = new VideoClipNameHelper.MediaDirectory();
        private int currentPlaying = 0;
        //
        //====================================================================================================================
        public MainWindow()
        {
            InitializeComponent();
            //
            //
            progressBar1.Minimum = 0.0;
            progressBar1.Maximum = 100.0;
            //progresBar1.ToolTipText = "";
            //
            //Task.Factory.StartNew(new Action(DbStatistics.CreateDbIfNeeded));
            //
            try
            {
                Dictionary<string, string> cDic = VideoClipNameHelper.ConfigData.ReadConfig(cp);
                //
                string key = "REPLAYGAINCOEFFICIENTVNC";
                if (cDic.ContainsKey(key))
                {
                    double rgc = double.Parse(cDic[key], System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture);
                    VolumeUtils.ReplayGainCoefficient = rgc;
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(string.Format("Error in {0}: {1}", VideoClipNameHelper.ConfigData.ConfigFileName, e.Message), "ConfigData.ReadConfig()", MessageBoxButton.OK, MessageBoxImage.Error);
                System.IO.File.WriteAllLines("errors.txt", new[] { e.Message + Environment.NewLine }, Encoding.UTF8);
                //
                return;
            }
            //
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WndProc);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                win1_SizeChanged(null, null);
                //
                wfh.Child = vlc;
                //
                vlc.AllowDrop = false;
                vlc.Volume = VolumeUtils.DefaultLevel;
                vlc.BackColor = System.Drawing.Color.DarkBlue;
                vlc.AutoLoop = false;
                vlc.AutoPlay = false;
                vlc.Toolbar = false;
                vlc.FullscreenEnabled = false;
                //
                //
                vlc.MediaPlayerEndReached += axVLCPlugin21_MediaPlayerEndReached;
                //
                //*** Eventy przestały się pojawiać 2016-7-1
                //vlc.play += axVLCPlugin21_play;
                //vlc.stop += axVLCPlugin21_stop;
                //vlc.pause += axVLCPlugin21_pause;
                vlc.MediaPlayerTimeChanged += axVLCPlugin21_MediaPlayerTimeChanged;
                //
                VideoClipNameHelper.CDBHandler.Initialize();
                //
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message + e1.StackTrace, "Window_Loaded", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        //====================================================================================================================
        //private static int WM_QUERYENDSESSION = 0x11;
        private static int WM_ENDSESSION = 0x16;
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_ENDSESSION)
            {
                //VideoClipNameHelper.CLogger.Write("WM_ENDSESSION");
                //
                vlc.VolumeToZero();
                vlc.playlist.stop();
                this.Close();
                //
                handled = true;
                //
            }
            return IntPtr.Zero;
        }

        public void Dispose()
        {
            //if(null != stat)
            {
                //stat.Dispose();
            }
            if (null != vlc)
            {
                vlc.Dispose();
                vlc = null;
            }
        }

        //====================================================================================================================
        private object playO = new object();
        private void playCurrent()
        {
            lock (playO)
            {
                win1.Title = "";
                progressBar1.Value = progressBar1.Minimum;
                buttonLikeImage.Source = Resources["Like"] as ImageSource;
                //
                if (0 == md.MediaFiles.Count) return;
                //
                string concatShortName = VideoClipData.GetNameWithoutResolution(md.MediaFiles[currentPlaying].ResolvedFile);
                win1.Title = System.IO.Path.GetFileName(md.MediaFiles[currentPlaying].OriginalFile);
                buttonLike.Tag = concatShortName as Object;
                if(VideoClipNameHelper.CDBHandler.IsLiked(concatShortName))
                {
                    buttonLikeImage.Source = Resources["NoLike"] as ImageSource;
                }
                //
                bool gainExist = false;
                double gain;
                if (VideoClipNameHelper.ReplayGain.ReadGain(md.MediaFiles[currentPlaying].ResolvedFile, out gain))
                {
                    gainExist = true;
                    int l = VolumeUtils.CalculateLevelAndReplayGain(gain);
                    //int l = Math.Min(Math.Max(0, VolumeUtils.GetDefaultLevel() + (int)gain),100);
                    VolumeUtils.SetMaxLevel(l);
                }
                else
                {
                    VolumeUtils.SetMaxLevel(VolumeUtils.DefaultLevel);
                }
                //
                VideoClipNameHelper.ScreenModes.DoEvents();
                vlc.playlist.items.clear();
                do { VideoClipNameHelper.ScreenModes.DoEvents(); } while (0 != vlc.playlist.items.count);
                vlc.playlist.add((new Uri(md.MediaFiles[currentPlaying].ResolvedFile)).ToString());
                VideoClipNameHelper.ScreenModes.DoEvents();
                vlc.VolumeToMaxAsync();
                vlc.playlist.playItem(0);
                do { VideoClipNameHelper.ScreenModes.DoEvents(); } while (!vlc.playlist.isPlaying);
                //
                progressBar1.ToolTip = System.IO.Path.GetFileNameWithoutExtension(md.MediaFiles[currentPlaying].OriginalFile) + " / " + (gainExist ? VolumeUtils.GetMaxLevel().ToString() : "?");
                SetButtonImage(buttonPlay, "Stop");
                //
                progressBar1.Value = progressBar1.Minimum;
                //
                //*** Event przestał działać
                axVLCPlugin21_play(null, null);
                //
                //
                Task.Run(() => { return VideoClipNameHelper.CDBHandler.UpdateData(concatShortName, updatenPlayed: true); }).ConfigureAwait(false);
                //
            }
        }

        private object stopO = new object();
        private void stopPlaying()
        {
            lock (stopO)
            {
                win1.Title = "";
                progressBar1.Value = progressBar1.Minimum;
                //
                buttonLike.Tag = null;
                buttonLikeImage.Source = Resources["Like"] as ImageSource;
                //
                SetButtonImage(buttonPlay, "Play");
                //
                progressBar1.ToolTip = "";
                //
                VideoClipNameHelper.ScreenModes.DoEvents();
                vlc.playlist.pause();
                VideoClipNameHelper.ScreenModes.DoEvents();
                vlc.playlist.stop();// hangs here *****
                do { VideoClipNameHelper.ScreenModes.DoEvents(); } while (vlc.playlist.isPlaying);
                vlc.playlist.items.clear();
                do { VideoClipNameHelper.ScreenModes.DoEvents(); } while (0 != vlc.playlist.items.count);
                //
                //*** Evevt przestał działać
                axVLCPlugin21_stop(null, null);
                //
            }
            //
        }
        //====================================================================================================================
        //private void axVLCPlugin21_MediaPlayerEndReached(object sender, EventArgs e)
        private void axVLCPlugin21_MediaPlayerEndReached(object sender, EventArgs e)
        {
            currentPlaying++;
            progressBar1.Value = progressBar1.Maximum;
            //
            if (currentPlaying >= md.MediaFiles.Count)
            {
                VideoClipNameHelper.ScreenModes.DoEvents();
                stopPlaying();
                VideoClipNameHelper.ScreenModes.DoEvents();
                md.MediaFiles.Clear();
                currentPlaying = 0;
                return;
            }
            playCurrent();
        }
        //====================================================================================================================
        private void axVLCPlugin21_play(object sender, EventArgs e)
        {
            if (0 == md.MediaFiles.Count()) return;
            //
            if (isBetweenTrack) return;
            //
            if (this.WindowState != System.Windows.WindowState.Maximized)
            {
                VideoClipNameHelper.ScreenModes.EnterFullScreenMode(this);
            }
        }

        private void axVLCPlugin21_pause(object sender, EventArgs e)
        {
            if (isBetweenTrack) return;
            //
            if (this.WindowState != System.Windows.WindowState.Normal)
            {
                VideoClipNameHelper.ScreenModes.LeaveFullScreenMode(this);
            }
        }

        private void axVLCPlugin21_stop(object sender, EventArgs e)
        {
            if (isBetweenTrack) return;
            //
            if (this.WindowState != System.Windows.WindowState.Normal)
            {
                VideoClipNameHelper.ScreenModes.LeaveFullScreenMode(this);
            }
        }
        //====================================================================================================================
        private void win1_DragOver(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.Copy;
        }

        private void win1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.Copy;
        }

        private void win1_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                //
                e.Effects = DragDropEffects.Copy;
                //
                stopPlaying();
                currentPlaying = 0;
                //
                string[] droppedFiles = (string[])e.Data.GetData(DataFormats.FileDrop);
                //
                //
                // >1 files/dirs: wczytujemy wszystkie, gramy od 0
                // 1: 
                //
                //filesToPlay = DirectoryCache.GetFilesFromDirectory(droppedFiles[0]);
                md = VideoClipNameHelper.DirectoryCache.GetFilesFromDirectory(droppedFiles[0]);
                //
                if (md.ArgumentIsDirectory)
                {
                    setRandom(VideoClipNameHelper.GeneralConfig.GetValueBool(md.HintData, "Random"));
                }
                else
                {
                    // argument: plik - gramy kolejno, ignorujac hint
                    setRandom(false);
                }
                //
                //
                //
                currentPlaying = 0;
                //
                if (isRandom && md.MediaFiles.Count > 1)
                {
                    Random rnd = new Random();
                    md.MediaFiles = md.MediaFiles.OrderBy(x => rnd.Next()).ToList<VideoClipNameHelper.MediaFile>();
                    currentPlaying = 0;
                }
                //
                //
                if (md.MediaFiles.Count > 0)
                {
                    playCurrent();
                }
                //
                //
                e.Handled = true;
            }
            //
            e.Effects = DragDropEffects.None;
            //
        }
        //====================================================================================================================

        //====================================================================================================================
    }//class
}//namespace
